/**
 * jquery fn drag and drop
 * 结构:
 * <div id=''>
 * 		<div class="drag-div"></div>
 * </div>
 * @param
 * options = {
 * 		outer: false, //whether can drag out the container
 * 		axis: '', //x or y
 * 		onmove: function(event){}
 * }
 * @author  tanggf
 */
(function($){
	$.fn.drag = function(options){
		//default setting
		options = $.extend({
			outer: false,
			axis: '',
			onmove: function(event){}
		}, options);
		
		return this.each(function(){
			_get_drag_(this, options);
		});	
	};
	
	function _get_drag_(ele, options){
		var $this = $(ele);
		var obj = $this.data("_wt_drag_");
		if( ! obj){
			obj = new _Drag_(ele, options);
			$this.data("_wt_drag_", obj);
		}
		return obj;
	}
	
	function _Drag_(ele, options){
		this.$ele = $(ele);
		this.options = options;
		this._init_();
	}
	
	_Drag_.prototype = {
		_init_: function(){
			this.$drag = this.$ele.children(".drag-div");
			this.$drag.attr('unselectable','on').css({'MozUserSelect':'none', 'position':'relative'});
			
			var self = this;
			this.$drag.mousedown(function(event){
				self._handle_mousedown(event);
			}).mousemove(function(event){				
				self._handle_mousemove(event);
				return false;
			}).mouseup(function(event){
				self._handle_mouseup(event);
			}).mouseleave(function(event){
				self._handle_mouseup(event);
			});
			
			this.paddingLeft = parseInt(this.$ele.css("padding-left").replace("px", "")) || 0;
			this.paddingTop = parseInt(this.$ele.css("padding-top").replace("px", "")) || 0;
			this.paddingRight = parseInt(this.$ele.css("padding-right").replace("px", "")) || 0;
			this.paddingBottom = parseInt(this.$ele.css("padding-bottom").replace("px", "")) || 0;			
			this.offset = this.$ele.offset();
			
			if( ! this.options.outer){				
				this._adjust_position();				
			}
		},
		
		_adjust_position: function(){			
			var maxleft = this.$ele.width() - this.$drag.outerWidth(true);
			var maxtop = this.$ele.height() - this.$drag.outerHeight(true);
			
			var os = this.$drag.offset();			
			var left = os.left - this.offset.left - this.paddingLeft;
			var top = os.top - this.offset.top - this.paddingTop;
			var ajleft = false;
			if(left < 0){
				left = 0;
				ajleft = true;
			}else if(left > maxleft){
				left = maxleft;
				ajleft = true;
			}
			
			var ajtop = false;
			if(top < 0){
				top = 0;
				ajtop = true;
			}else if(top > maxtop){
				top = maxtop;
				ajtop = true;
			}
			
			var pos = {};
			if(ajleft){
				pos['left'] = left;
			}
			if(ajtop){
				pos['top'] = top;
			}
			this.$drag.css(pos);		
		},
		
		_handle_mousedown: function(event){
			this.clicked = true;
			this.stop = event.pageY;
			this.sleft = event.pageX;		
			this.oldos = this.$drag.offset();
		},
		
		_handle_mousemove: function(event){
			if(this.clicked){							
				this._move_(event);
			}
		},
		
		_handle_mouseup: function(event){
			this.clicked = false;			
		},
		
		_move_: function(event){			
			var gleft = event.pageX - this.sleft;
			var gtop = event.pageY - this.stop;
			var left = parseInt(this.$drag.css("left").replace("px", "")) || 0;
			var top = parseInt(this.$drag.css("top").replace("px", "")) || 0;
			left += gleft;
			top += gtop;
			
			if(this.options.axis == 'x'){
				pos = {"left": left};
			}else if(this.options.axis == 'y'){
				pos = {"top": top};
			}else{
				pos = {"left": left, "top": top};
			}		
			
			this.$drag.css(pos);			
			
			if( ! this.options.outer){
				this._adjust_position();
			}	
		
						
			this.sleft = event.pageX;
			this.stop = event.pageY;		
			
			this.options.onmove(event);
		}
	};
})(jQuery);